package alibaba

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

const (
	DefaultHost = "https://gw.open.1688.com/openapi/"
)

var (
	AppKey    = "9750267"
	AppSecret = "fAX3mMpbDKJ"
)

type (
	AliDecryptJsons struct {
		Result        interface{} `json:"result"`
		TotalRecord   int         `json:"totalRecord"`
		ErrorCode     string      `json:"errorCode"`
		Success       bool        `json:"success"`
		ErrorMessage  string      `json:"errorMessage"`
		AccessToken   string      `json:"access_token"`
		AliId         string      `json:"aliId"`
		ResourceOwner string      `json:"resource_owner"`
		ExpiresIn     string      `json:"expires_in"`
		MemberId      string      `json:"memberId"`
	}
)

// GetAlibabaAPI 调用阿里巴巴开放平台 API
func GetAlibabaAPI(method string, param map[string]string) (AliDecryptJsons, error) {
	timestamp := time.Now().Format("2006-01-02 15:04:05")
	responseVal, err := fetchAPI(AppKey, DefaultHost, method, timestamp, param, true)
	fmt.Printf("222:%v\n", responseVal)
	if err != nil {
		log.Printf("API 调用失败: method=%s, error=%v", method, err)
		return AliDecryptJsons{}, fmt.Errorf("API 调用失败: %w", err)
	}

	var res AliDecryptJsons
	if err := json.NewDecoder(bytes.NewReader([]byte(responseVal))).Decode(&res); err != nil {
		return AliDecryptJsons{}, fmt.Errorf("解析响应失败: %w", err)
	}
	return res, nil
}

// fetchAPI 封装通用的 API 请求逻辑
func fetchAPI(appKey, host, method, timestamp string, data map[string]string, needSignature bool) (string, error) {
	methodPath := strings.Replace(method, ":", "/", -1)
	u := host + "param2/1/" + methodPath + "/" + appKey

	if needSignature {
		data["_aop_signature"] = generateSignature(methodPath, appKey, data)
	}

	params := url.Values{}
	for k, v := range data {
		params.Add(k, v)
	}

	resp, err := http.PostForm(u, params)
	if err != nil {
		return "", fmt.Errorf("HTTP 请求失败: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("读取响应失败: %w", err)
	}
	return string(body), nil
}

// generateSignature 生成签名
func generateSignature(methodPath, appKey string, data map[string]string) string {
	var builder strings.Builder
	builder.WriteString("param2/1/" + methodPath + "/" + appKey)

	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, k := range keys {
		builder.WriteString(k + data[k])
	}

	h := hmac.New(sha1.New, []byte(AppSecret))
	h.Write([]byte(builder.String()))
	return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
